package day05;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;

/**
 * @title: App64_2
 * @author: lbj
 * @date: 2022/5/2 8:42 上午
 * @description: TODO 类描述
 */


public class App64_2 {

    public static void main(String[] args) {
        final ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(new Target1());//设置目标对象

        // 添加通知，MethodInterceptor 是环绕通知
//        proxyFactory.addAdvice((MethodInterceptor) invocation -> {
//            try {
//                System.out.println("before...");
//                return invocation.proceed(); //调用目标
//            } finally {
//                System.out.println("after...");
//            }
//        });

        final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(* foo())");

        proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut,(MethodInterceptor)invocation->{
           try {
                System.out.println("before1...");
                return invocation.proceed(); //调用目标
            } finally {
                System.out.println("after1...");
            }
        }));

        proxyFactory.addAdvisor(new DefaultPointcutAdvisor(pointcut,(MethodInterceptor)invocation->{
            try {
                System.out.println("before2...");
                return invocation.proceed(); //调用目标
            } finally {
                System.out.println("after2...");
            }
        }));

        proxyFactory.addInterface(I1.class);
        //强制使用 cglib 代理
//        proxyFactory.setProxyTargetClass(true);
        //cglib 代理
//        final Target1 proxy = (Target1) proxyFactory.getProxy();
        // jdk 代理
        I1 proxy = (I1) proxyFactory.getProxy();
        System.out.println(proxy.getClass());
        proxy.foo();
        proxy.bar();
    }

    interface  I1{
        void foo();
        void bar();
    }

    static class Target1 implements I1{
        @Override
        public void foo() {
            System.out.println("target1 foo");
        }

        @Override
        public void bar() {
            System.out.println("target1 bar");
        }
    }
}
